﻿using System;
using System.Net;
using System.Windows;
using System.Data.Linq;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Linq;
using System.IO;


namespace Organizer.Model
{
    public class OrganizerDataContext : DataContext
    {

        private static OrganizerDataContext _obj;
        public static OrganizerDataContext Instance
        {
            get
            {
                if (_obj == null)
                    _obj = new OrganizerDataContext();
                if (!_obj.DatabaseExists())
                    _obj.CreateDatabase();
                return _obj;
            }
        }

        public Table<User> Users;
        public Table<Man> Mans;
        public Table<Settings> Settings;
        public Table<Task> Tasks;
        public Table<Category> Categories;
        public Table<CategoryTask> CategoryTasks;
        public Table<Note> Notes;
        public Table<Organization> Organizations;

        public Task GetTaskById(Guid id)
        {
            IQueryable<Task> query = Tasks.Where(t => t.Id == id).Select(t => t);
            return query.First();
        }

        public Note GetNoteById(Guid id)
        {
            IQueryable<Note> query = Notes.Where(t => t.Id == id).Select(t => t);
            if (query.Count() != 0)
                return query.First();
            else
                return null;
        }

        public Man GetManById(Guid id)
        {
            IQueryable<Man> query = Mans.Where(t => t.Id == id).Select(t => t);
            if (query.Count() != 0)
                return query.First();
            else
                return null;
        }

        public Organization GetOrganizationsById(Guid id)
        {
            IQueryable<Organization> query = Organizations.Where(t => t.Id == id).Select(t => t);
            if (query.Count() != 0)
                return query.First();
            else
            {
                return null;
            }
        }

        protected OrganizerDataContext()
            : base("Data Source=isostore:/DB.sdf")
        {
            if (DatabaseExists())
                return;
            else
                CreateDatabase();


            this.Log = new MyTextWriter();
            //if (DatabaseExists())
            //    DeleteDatabase();
            //CreateDatabase();
            var m1 = new Man("Jane", "Fibber", "");
            var m2 = new Man("Mary", "Smith", "");
            var m3 = new Man("Kate", "Polsen", "");
            Mans.InsertAllOnSubmit(new[] { m1, m2, m3, Man.None });
            SubmitChanges();

            User u1 = new User("m1user", "asd", m1);
            User u2 = new User("m2user", "asd2", m2);
            User u3 = new User("m1secondUser", "asd3", m1);
            Users.InsertAllOnSubmit(new[] { u1, u2, u3 });
            SubmitChanges();

            Users.DeleteOnSubmit(u2);
            SubmitChanges();

            Settings s1 = new Settings(u1);
            Settings s2 = new Settings(u1);
            Settings s3 = new Settings(u3);
            SubmitChanges();

            Task t1 = new Task("test task 1");
            Task t2 = new Task("test task 2");         
            Tasks.InsertOnSubmit(t1);           
            SubmitChanges();

            Category c1 = new Category("category 1", "description");
            Category c2 = new Category("category 2", "description");
            Category c3 = new Category("category 3", "description");
            Categories.InsertAllOnSubmit(new[] { c1, c2, c3 });
            SubmitChanges();

            Categories.DeleteOnSubmit(c3);
            SubmitChanges();

            CategoryTask ct1 = new CategoryTask(t1, c1);
            CategoryTask ct2 = new CategoryTask(t1, c2);
            CategoryTask ct3 = new CategoryTask(t2, c1);
            CategoryTasks.InsertAllOnSubmit(new[] { ct1, ct2, ct3 });
            SubmitChanges();

            Categories.DeleteOnSubmit(c1);
            SubmitChanges();

            CategoryTasks.DeleteOnSubmit(ct3);
            SubmitChanges();

            Note n1 = new Note("note 1");
            Note n2 = new Note("note 2");
            Note n3 = new Note("note 3");
            Notes.InsertAllOnSubmit(new[] { n1, n2, n3 });
            SubmitChanges();
            
            Organization o1 = new Organization("org 1", "descr 1");
            Organization o2 = new Organization("org 2", "descr 2");
            Organization o3 = new Organization("org 3", "descr 3");
            Organizations.InsertAllOnSubmit(new[] { o1, o2, o3, Organization.None });
            SubmitChanges();

            Organizations.DeleteOnSubmit(o3);
            SubmitChanges();
        }

        #region loger
        protected class MyTextWriter : TextWriter
        {

            List<string> results = new List<string>();

            public override void Close()
            {
                return;
            }
            public override void Flush()
            {
                return;
            }

            public override void Write(string format, object arg0)
            {
                results.Add(string.Format(format, arg0));
            }

            public override void Write(string format, object arg0, object arg1)
            {
                results.Add(string.Format(format, arg0, arg1));
            }

            public override void Write(string format, params object[] arg)
            {
                results.Add(string.Format(format, arg));
            }

            public override void Write(string value)
            {
                results.Add(value);
            }

            public override void Write(object value)
            {
                results.Add(value.ToString());
            }

            public override void WriteLine(string format, object arg0)
            {
                results.Add(string.Format(format, arg0));
            }

            public override void WriteLine(string format, object arg0, object arg1)
            {
                results.Add(string.Format(format, arg0, arg1));
            }

            public override void WriteLine(string format, params object[] arg)
            {
                results.Add(string.Format(format, arg));
            }

            public override void WriteLine(string value)
            {
                results.Add(value);
            }

            public override void WriteLine(object value)
            {
                results.Add(value.ToString());
            }

            public override System.Text.Encoding Encoding
            {
                get { throw new NotImplementedException(); }
            }
        }
        #endregion

    }
}
